有些時候我們需要傳參數到路由中,以動態的方式匹配對的資料及畫面:userId
表示為一個自定義的參數,我們可以透過 this.$route.params
.userId 來取得參數的值。
{
path: 'user/:userId',
name: 'User',
component: () => import('@/views/User.vue')
}
今天如果我們希望參數是可以非必填的,就可以使用?
來代表optional params
{
path: '/offers/:member?',
...
}
vue-router 分為兩種模式:hash(預設)、historyhash mode
ex:http://website.com/#user/id
Vue Router 的默認模式,使用 URL 的 hash 來模擬一個完整的URL,hash 雖然出現在 URL 中,但不會被包含在 HTTP 請求中,對後端完全沒有影響,於是當URL 改變時頁面不會重新加載。
history mode
ex:http://website.com/user/id
history模式少掉了#
比較像完整的URL網址,是不是也比較簡單好看,而且這模式利用history.pushState 來完成URL跳轉而無須重新載入頁面,唯一要特別注意到當您的URL匹配不到任何靜態資源時,需配置重新導向到同一個頁面,如index.html。後端配置例子可以看這邊
const router = new VueRouter({
mode: 'history',
routes,
...
})
我們來回顧這張圖,巢狀路由是指路由有多階層,所以我們用多層的路由視圖 router-view
,且配置好子路由childern
如圖,我們在app.vue有配置 router-view
,然後在Layout.vue再配置一個 router-view
及其子路由Dashboard.vue、User.vue、Setting.vue
{
path: '/home',
component: Layout,
meta: { requireAuth: true },
childern: [
{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/Dashboard.vue')
},
{
path: 'user/:userId',
name: 'User',
component: () => import('@/views/User.vue')
},
{
path: 'setting',
name: 'Setting',
component: () => import('@/views/Setting.vue')
}
]
}
需注意到,以/
開頭的巢狀路由會被當作根目錄符號來運用,children 底下的 path 不加/
讓其自動匹配父層路由。
// 不需要再配置路徑'/dashboard','dashboard'即可
childern: [
{
path: '/dashboard', // X
name: 'Dashboard',
component: () => import('@/views/Dashboard.vue')
}
]
redirect:
在昨天,我有教大家捕獲所有路由或匹配不到時,則重定向到 404page,今天在加碼教大家一個使用命名(name)來重定向
const router = new VueRouter({
routes: [
{ path: '/bar', redirect: { name: 'foo' }}
]
})
alias:
重定向的意思是,當用戶訪問/a時,URL將會被替換成/b,然後匹配路由為/b。
c 的別名是 d,意味著,當用戶訪問/d時,URL會保持為/d,但是路由匹配則為/c,就像用戶訪問/c一樣,路徑不變,代表一個路由有多個匹配路徑的別名。
const router = new VueRouter({
routes: [
{ path: '/a', redirect: '/b' },
{ path: '/c', component: C, alias: '/d' }
]
})
vue-router提供的路由守衛主要用來通過跳轉或取消的方式守衛導航。有多種方式植入路由導航過程中:全局守衛
,獨享守衛
,元件內守衛
。
首先我們來做個簡易的驗證,還記得我們的元訊息meta: { requireAuth: true }
有設定驗證,這樣該路由(包含子路由)在路由改變時就會需要檢查。
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
const token = VueCookies.get('token')
const isLogin = this.checkLogin(token) // 這裡寫驗證機制(自己客製化)
if (isLogin) {
next() // 往下執行
} else {
//如果使用者token無效則跳轉到login頁面
if (to.path !== '/login') {
next('/login')
} else {
next() // 往下執行
}
}
} else {
next() // 往下執行
}
})
剛剛我們用的beforeEach
即是全局前置守衛,其中三個參數to
、 from
、 next
:
1.to:即將要進入的目標路由物件。
2.from:當前導航即將要離開的路由物件。
3.next:呼叫該方法後,才能進入下一個鉤子函式:
必須注意,確保所有的邏輯狀態都要調用 next()一次,否則鉤子就不會被解析(resolved)。
後置守衛和前置守衛不同的是afterEach
不接收第三個參數 next(),也意味著不會改變導航本身。
router.afterEach((to, from)=>{
console.log(to)
console.log(from)
})
你可以在路由配置上直接定義beforeEnter
守衛,這些守衛與全局前置守衛的方法參數一樣。
const router = new VueRouter({
routes: [
{
path: '/admin',
component: Admin,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
我們可以在component裡面直接定義導航守衛,元件的導航守衛有三種:
beforeRouteEnter
:beforeRouteEnter (to, from, next) {
next(vm => {
console.log(vm)
})
}
beforeRouteUpdate
:beforeRouteLeave
:beforeRouteLeave
來暫止用戶在還未保存修改前突然離開。beforeRouteLeave (to, from, next) {
const answer = window.confirm('您是否離開此頁?您尚有改變未儲存!')
if (answer) {
next()
} else {
next(false)
}
}
完整路由程式碼:
import Vue from 'vue'
import VueRouter from 'vue-router'
import VueCookies from 'vue-cookies'
import Login from '@/views/Login'
import Layout from '@/views/Layout'
Vue.use(VueRouter)
const routes = [
{
path: '/login',
name: 'Login',
component: Login
},
{
path: '/',
name: 'redirect',
redirect: '/home/dashboard'
},
{
path: '/home',
component: Layout,
meta: { requireAuth: true },
childern: [
{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/Dashboard.vue')
},
{
path: 'user/:userId',
name: 'User',
component: () => import('@/views/User.vue')
},
{
path: 'setting',
name: 'Setting',
component: () => import('@/views/Setting.vue')
}
]
},
{
path: '/404',
name: '404',
component: () => import('@/components/Page404'),
hidden: true
},
{
path: '*',
redirect: '/404',
hidden: true
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
const token = VueCookies.get('token')
const isLogin = this.checkLogin(token) // 這裡寫驗證機制(自己客製化)
if (isLogin) {
next() // 往下執行
} else {
//如果使用者token無效則跳轉到login頁面
if (to.path !== '/login') {
next('/login')
} else {
next() // 往下執行
}
}
} else {
next() // 往下執行
}
})
export default router
參考文件:Vue Router
有任何問題歡迎下方留言,如果喜歡我的文章別忘了按讚、訂閱追蹤加分享唷!!
---我是分隔線-----------------------------------------------------------
PollyPO技術-前端設計轉前端工程師-JS踩坑雜記 30 天
喬依司-實作經典 JavaScript 30
五百億-Vue CLI + Firebase 雲端資料庫 30天打造簡易部落格及後臺管理
eien_zheng-前端小嘍嘍的Golang學習旅程_The journey of learning Golang